import { Request, Response } from "express";
import { AuthService } from "../services/auth.service";
import { UserService } from "../services/user.service";
import { RegisterRequest, LoginRequest } from "../types/index";
import { BcryptUtil } from "../utils/bcrypt.utils";

export class AuthController {
  private authService: AuthService;
  private userService: UserService;

  constructor() {
    this.authService = new AuthService();
    this.userService = new UserService();
  }

  /**
   * 处理用户注册
   */
  register = async (req: Request, res: Response) => {
    try {
      const data: RegisterRequest = req.body;

      // 验证请求数据
      if (!data.username || !data.email || !data.password) {
        return res.status(400).json({
          code: 400,
          success: false,
          message: "All fields are required",
          data: null,
        });
      }

      const user = await this.authService.register(data);
      const { password, ...userWithoutPassword } = user;

      return res.status(201).json({
        code: 201,
        success: true,
        message: "User registered successfully",
        data: userWithoutPassword,
        // user: userWithoutPassword,
      });
    } catch (error) {
      if (error instanceof Error) {
        return res.status(400).json({
          code: 400,
          success: false,
          message: error.message,
          data: null,
        });
      }
      return res.status(500).json({
        code: 500,
        success: false,
        message: "Server error",
        data: null,
      });
    }
  };

  /**
   * 处理用户登录
   */
  login = async (req: Request, res: Response) => {
    try {
      const data: LoginRequest = req.body;

      // 验证请求数据
      if (
        !((data.email && data.password) || (data.username && data.password))
      ) {
        return res.status(400).json({
          code: 400,
          success: false,
          message: "Email and password or username are required",
          data: null,
        });
      }

      const result = await this.authService.login(data);
      const { user, token } = result;

      // 提取需要存储到session的用户信息（排除敏感数据）
      const userSessionData = {
        userId: user.id,
        username: user.username,
        email: user.email,
        role: user.role,
      };
      req.session.user = userSessionData;
      // console.log("----------");
      req.session.save((err) => {
        if (err) {
          console.error("Failed to save session:", err);
          return res.status(500).json({
            code: 500,
            success: false,
            message: "Failed to save session",
            data: null,
          });
        }

        // 登录成功响应
        res.header("Authorization", `Bearer ${token}`);
        return res.status(200).json({
          code: 200,
          success: true,
          message: "Login successful",
          data: {
            data: userSessionData,
            token,
          },
        });
      });
    } catch (error) {
      if (error instanceof Error) {
        return res.status(400).json({
          code: 400,
          success: false,
          message: error.message,
          data: null,
        });
      }
      return res.status(500).json({
        code: 500,
        success: false,
        message: "Server error",
        data: null,
      });
    }
  };

  /**
   * 获取当前登录用户信息
   */
  getCurrentUser = async (req: Request, res: Response) => {
    try {
      // 优先从session获取用户信息
      if (req.session.user) {
        return res.status(200).json({
          code: 200,
          success: true,
          message: "User retrieved successfully",
          data: { ...req.session.user },
        });
      }
      // 如果session中没有，再从JWT验证的用户信息获取
      if (!req?.user) {
        return res.status(401).json({
          code: 401,
          success: false,
          message: "Authentication required",
          data: null,
        });
      }

      const user = await this.authService.getUserById(req.user.userId);

      if (!user) {
        return res.status(601).json({
          code: 601,
          success: false,
          message: "User not found",
          data: null,
        });
      }

      const { password, ...userWithoutPassword } = user;

      return res.status(200).json({
        code: 200,
        success: true,
        message: "User found",
        data: userWithoutPassword,
        // user: userWithoutPassword,
      });
    } catch (error) {
      return res.status(500).json({
        code: 500,
        success: false,
        message: "Server error",
        data: null,
      });
    }
  };
  /**
   * 用户登出 - 销毁session
   */
  logout = async (req: Request, res: Response) => {
    req.session.user = undefined;
    req.session.destroy((err) => {
      if (err) {
        return res
          .status(500)
          .json({
            code: 500,
            success: false,
            message: "Failed to logout",
            data: null,
          })
          .end();
      }

      res.status(200).json({
        code: 200,
        success: true,
        message: "Logout successful",
        data: null,
      });
    });
  };

  changePassword = async (req: Request, res: Response) => {
    const { current_password, new_password } = req.body;
    if (!current_password || !new_password) {
      return res.status(1002).json({
        code: 1002,
        success: false,
        message: "All fields are required",
        data: null,
      });
    }
    const userId = req.session.user?.userId;
    console.log("req.session.user: ", req.session.user);
    console.log("userId: " + userId);
    const user = await this.authService.getUserById(String(userId));
    const isPasswordValid = await BcryptUtil.verifyPassword(
      current_password,
      user.password
    );
    if (!isPasswordValid) {
      return res.status(1004).json({
        code: 1004,
        success: false,
        message: "Current password is incorrect",
        data: null,
      });
    }
    const hashedPassword = await BcryptUtil.encodePassword(new_password);
    this.authService.changePassword(userId as number, hashedPassword);
    return res.status(200).json({
      code: 200,
      success: true,
      message: "Password changed successfully",
      data: null,
    });
  };
  resetPassword = async (req: Request, res: Response) => {
    const { userId } = req.params;
    const hashedPassword = await BcryptUtil.encodePassword(
      process.env.RESET_PASSWD || "123456"
    );
    await this.authService.changePassword(Number(userId), hashedPassword);
    return res.status(200).json({
      code: 200,
      success: true,
      message: "Password reset successfully",
      data: null,
    });
  };
}
